package com.zsk.tool.io;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author keke
 * @date 2020/11/14
 */
public class FileUtil {

    private final static Logger log = LoggerFactory.getLogger(FileUtil.class.getClass());

    public static boolean fileExist(String path) {
        return new File(path).exists();
    }

    public static boolean createDir(String dir) {
        File file = new File(dir);
        if (!file.isDirectory()) {
            file.mkdirs();
        }
        return true;
    }

    /**
     * 清空一个文件夹，如果不存在就创建
     * 
     * @param dir
     * @return
     */
    public static boolean clearDir(String dir) {
        File file = new File(dir);
        if (!file.isDirectory()) {
            file.mkdirs();
            return true;
        }
        File[] files = file.listFiles();
        for (File f : files) {
            deleteFile(f);
        }
        return true;
    }

    /**
     * 删除文件夹或文件
     * 
     * @param file
     * @return
     */
    public static boolean deleteFile(File file) {
        if (!file.exists()) {
            return false;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                deleteFile(f);
            }
        }
        return file.delete();
    }

    /**
     * 深度搜索遍历文件夹
     * 
     * @param dirPath
     * @param list
     */
    public static void listFileByDfs(String dirPath, List<String> list) {
        File file = new File(dirPath);
        File[] files = file.listFiles();
        for (File tmpFile : files) {
            if (tmpFile.isDirectory()) {
                listFileByDfs(tmpFile.getAbsolutePath(), list);
            } else {
                list.add(tmpFile.getAbsolutePath());
            }
        }
    }

    /**
     * 广度搜索遍历文件夹
     * 
     * @param dirPath
     * @param list
     */
    public static List<String> listFileByBfs(String dirPath) {
        List<String> list = new ArrayList<>();
        File file = new File(dirPath);
        File[] fs = file.listFiles();
        Queue<File> queue = new LinkedList<>();

        // 遍历第一层
        for (File f : fs) {
            // 把第一层文件夹加入队列
            if (f.isDirectory()) {
                queue.offer(f);
            } else {
                list.add(f.getAbsolutePath());
            }
        }
        // 逐层搜索下去
        while (!queue.isEmpty()) {
            // 从队列头取一个元素
            File fileTemp = queue.poll();
            File[] fileListTemp = fileTemp.listFiles();
            for (File f : fileListTemp) {
                if (f.isDirectory()) {
                    queue.offer(f);
                } else {
                    list.add(f.getAbsolutePath());
                }
            }
        }
        return list;
    }

    public static boolean writeFile(byte[] bytes, String path) {
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(path))) {
            File dir = new File(path).getParentFile();
            if (!dir.isDirectory()) {
                dir.mkdirs();
            }
            int len = bytes.length;
            for (int i = 0; i < len; i++) {
                bytes[i] = (byte)((int)bytes[i]);
            }
            dos.write(bytes);
            dos.flush();
            return true;
        } catch (Exception e) {
            log.error(e.toString());
        }
        return false;
    }

    public static byte[] readFile(String path) {
        try (DataInputStream in = new DataInputStream(new FileInputStream(path))) {
            byte[] b = new byte[in.available()];
            in.read(b);
            return b;
        } catch (Exception e) {
            log.error(e.toString());
        }
        return new byte[0];
    }

}
